/**
 * Created by mooshroom on 2015-07-30.
 * webScoket通信组件
 * 版本：V2.0.0
 *
 */
define([
    "avalon",
    'text!../../ui/ws/ws.html',
    'css!../../ui/ws/ws.css'
], function (avalon, html,css) {
    var widget = avalon.ui.ws = function (element, data, vmodels) {
        var options = data.wsOptions
        var objId = data.wsId
        var vm = avalon.define({
            $id: objId,
            $init: function () {
                ///初始化配置
                //扫描
                avalon.scan(element, [vm].concat(vmodels))
                if (typeof vm.onInit === "function") {
                    vm.onInit.call(element, vm, options, vmodels)
                }

                vm.start()


            },
            $remove: function () {
//                element.innerHTML = ""

            },
            onInit: function () {

            },

            /*具体实现*/
            state:0,//连接状态：0-尚未连接；1-连接正常；2-已经断线
            link:{},//连接实体

            server:'',//服务器地址格式；'ws://121.41.115.217:9999'

            reStartTime:3000,//断线重连时间
            heartTime:50000,//心跳间隔时间
            onopen: function () {//成功连接之后的额外回调

            },
            onerror: function () {//连接失败的额外回调

            },
            onclose: function () {//连接被关闭的额外回调

            },
            onmessage:function(){//消息接受是的额外回调

            },
            /*创建连接*/
            start: function () {
                if(vm.server!=''){
                    var link;
                    var server=vm.server

                    if ('WebSocket' in window) {
                        link = new WebSocket(server);
                    } else if ('MozWebSocket' in window) {
                        link = new MozWebSocket(server);
                    } else {
                        alert('WebSocket is not supported by this browser.');
                        return
                    }


                    //添加时间监听
                    link.onerror = function (evt) {
//产生异常
                        vm.onerror(evt)
                        vm.state = 2;
                        console.log("websocket连接错误：" + server, 1, 3000)
                        setTimeout(function(){
                            vm.reStart()
                        },vm.reStartTime)
                    };

                    link.onopen = function (evt) {
//已经建立连接
                        vm.onopen(evt)
                        console.log("websocket连接成功：" + server, 1, 3000);
                        console.log("连接成功："+evt)
                        vm.state = 1;





                        //保持心跳
                        setInterval(function(){
                            link.send("\r\n")
                        },vm.heartTime)
                    };

                    link.onclose = function (evt) {
//已经关闭连接
                        vm.onclose(evt)
                        console.log("websocket连接已关闭：" + server, 1, 3000);
                        console.log("连接关闭："+evt)
                        vm.state = 2;

                        setTimeout(function(){
                            vm.reStart()
                        },vm.reStartTime)
                    };

                    link.onmessage = function (evt) {
                        vm.onmessage(evt)
                        vm.listen(evt)
                    };
                    window.webSocketLinks={}
                    window.webSocketLinks[objId]=link
                }
            },

            /*发送数据*/
            call: function (v,i,obj) {
                if(typeof obj=="string"){
                    //直接发送
                    window.webSocketLinks[objId].send(v+","+i+","+obj+'\r\n')

                }
                else{
                    var d=JSON.stringify(obj)

                    ready2Send= d.replace(/,/g,"[|]")//字符替换
                    //ready2Send=encodeURIComponent(d)//加码

                    console.log(ready2Send+'<='+d)

                    var p=v+","+i+","+ready2Send+"\r\n"//拼接指令极其版本

                    window.webSocketLinks[objId].send(p)
                }
            },


            /*注册监听*/
            addListen: function (name, fn) {
                if (typeof name == "string") {
                    if (typeof fn == "function") {
                        try{
                            ws.todo[name] = fn
                            console.log("监听"+name+"事件的方法已就绪")
                        }catch (e){
                            console.log(e)
                        }

                    }
                    else {
                        console.log("传入的方法必须为函数:" + fn)
                    }
                }
                else {
                    console.log("传入的名称必须为字符串:" + name)
                }
            },

            /*监听消息*/
            todo:{},
            listen: function (evt) {
                //收到服务器消息，使用evt.data提取
                //检测分包
                ws.res=ws.res+evt.data
                if(ws.res.slice(-2)==='\r\n') {
                    //分包为末尾
                    var ins = ws.res.split(',');//转换为数组
                    var targetFn = ins[1];//解析目标动作

//            var decoded=ins[2].replace(/\[\|\]/g,",")
                    //var decoded=decodeURIComponent(ins[2])//数据解码

                    var v=ins.splice(2,ins.length)//剔除前两位，剩余部分为参数部分

//            var data = JSON.parse(decoded)//转换为json

                    ws.res=''//清空分包缓存

                    console.log(ins+","+targetFn)
                    //执行回调
                    if (typeof ws.todo[targetFn] == "function") {
                        ws.todo[targetFn](v);//传入数据
                    } else {
                        console.log("服务器返回了一个不认识的家伙：" + targetFn)
                    }
                }
            },
            /*断线重连*/
            reStart: function () {
                vm.start()
            }






        })
        //传入配置，传入方法就是把option里面的属性和刚才创建的VM里面的属性搅拌起来
        avalon.mix(vm, options)

        //最后把创建好的VM赋值给当前域下面的以VM的ID为名称的对象里面去，我们就能在当前域调用了
        return this[objId] = vm
    }
    //这是给默认配置的地方，在这里暂时还用不上
    widget.defaults = {}

    //传说一定要这样,不过我注释了也没有什么异常
    return avalon
})